package com.oauth.facebook.server.util;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
import java.util.StringTokenizer;

import com.oauth.facebook.client.beans.FacebookUser;
import com.oauth.facebook.server.beans.FbUser;
import com.oauth.service.application.global.beans.Birthday;
import com.restfb.Connection;
import com.restfb.types.Post;
import com.restfb.types.User;

public class FacebookUtil {

	public static final String BIRTHDAY_FQL_QUERY = "SELECT uid,first_name,last_name,profile_url,pic_square,birthday_date FROM user WHERE uid IN "
			+ "(SELECT uid2 FROM friend WHERE uid1 = me())AND strlen(birthday_date) != 0 "
			+ "and (substr(birthday_date,0,5) >= '?' and substr(birthday_date,0,5) <= '@')";

	private static final SimpleDateFormat format = new SimpleDateFormat("MM/dd");

	public static List<FacebookUser> getUsers(Connection<User> pConnections) {
		List<FacebookUser> users = new ArrayList<FacebookUser>();
		if (pConnections != null) {
			for (User user : pConnections.getData()) {
				users.add(getUser(user));
			}
		}
		return users;
	}

	public static List<Birthday> getBirthdays(List<FbUser> pUserList) {
		List<Birthday> birthdayList = new ArrayList<Birthday>();
		if (pUserList != null) {
			for (FbUser user : pUserList) {
				Birthday birthday = getBirthday(user);
				if (birthday != null) {
					birthdayList.add(birthday);
				}
			}
		}
		return birthdayList;
	}

	public static String getBirthdayFQLQuery(int pBirthdayInterval) {
		Calendar current = Calendar.getInstance();
		Calendar future = getFuture(pBirthdayInterval);
		String fqlQuery = BIRTHDAY_FQL_QUERY.replace("?", format.format(current.getTime()));
		fqlQuery = fqlQuery.replace("@", format.format(future.getTime()));
		return fqlQuery;
	}

	private static Birthday getBirthday(FbUser pUser) {

		Calendar birthCalendar = getBirthCalendar(pUser.getBirthdayDate());
		if (birthCalendar == null) {
			return null;
		}
		String birthString = getBirthString(birthCalendar);
		if (birthString == null) {
			return null;
		}

		Birthday birthday = new Birthday();
		birthday.setDisplayName(pUser.getFirstName() + " " + pUser.getLastName());
		birthday.setPictureUrl(pUser.getPicSquare());
		birthday.setProfileUrl(pUser.getProfileUrl());
		birthday.setBirthDay(birthString);
		return birthday;
	}

	private static Calendar getBirthCalendar(String dob) {
		// NOTE: Since most people don't have year, set it to 2000 as default.

		try {
			int year, month, day;
			StringTokenizer st = new StringTokenizer(dob, "/");
			month = Integer.parseInt(st.nextToken());
			day = Integer.parseInt(st.nextToken());
			year = st.hasMoreTokens() ? Integer.parseInt(st.nextToken()) : 2000;
			return new GregorianCalendar(year, month - 1, day);
		} catch (Exception e) {
			return null;
		}
	}

	private static Calendar getFuture(int pBirthdayInterval) {
		Calendar future = Calendar.getInstance();
		future.add(Calendar.DAY_OF_MONTH, pBirthdayInterval);
		return future;
	}

	private static String getBirthString(Calendar birth) {
		return birth.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.US) + " "
				+ birth.get(Calendar.DAY_OF_MONTH);
	}

	public static List<FacebookUser> getUpdates(Connection<Post> pUpdates) {
		List<FacebookUser> users = new ArrayList<FacebookUser>();
		if (pUpdates != null) {
			for (Post update : pUpdates.getData()) {
				if (update.getType().equals("status")) {
					FacebookUser user = new FacebookUser();
					user.setName(update.getFrom().getName());
					user.setId(Long.parseLong(update.getFrom().getId()));
					user.setStatus(update.getMessage());
					users.add(user);
				}
				// System.out.println("key=" + update.getUpdateKey());
			}
		}
		return users;
	}

	public static FacebookUser getUser(User fbUser) {
		FacebookUser user = new FacebookUser();
		user.setName(fbUser.getName());
		System.out.println("Fbuserid=" + fbUser.getId());
		user.setId(Long.parseLong(fbUser.getId()));
		user.setProfileImageUrl(fbUser.getPicture());
		user.setBirthday(fbUser.getBirthday());
		System.out.println(user);
		return user;
	}

}
